package bjm.conf;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.Collection;

/****
 * @Author:Chs
 * @Description:权限
 * @Date 2020/11/28 10:35
 *****/
@Component
public class CustomAccessDecisionManager
        implements AccessDecisionManager {

    /***
     * 判断当前登录的用户是否具备当前请求的URL所需要的角色信息
     * 如果不具备，就抛出异常。否则不做任何操作
     * @param auth 用户当前的登录信息
     * @param object FilterInvocation对象
     * @param ca 当前URL所需的角色
     * FilterInvocationSecurityMetadataSource中的getAttributes的返回值
     */
    @Override
    public void decide(Authentication auth,
                       Object object,
                       Collection<ConfigAttribute> ca){
        Collection<? extends GrantedAuthority> auths = auth.getAuthorities();
        //角色信息匹配
        for (ConfigAttribute configAttribute : ca) {
            //所需角色如果是ROLE_LOGIN或者当前用户已登录则结束
            if ("ROLE_LOGIN".equals(configAttribute.getAttribute())
                    && auth instanceof UsernamePasswordAuthenticationToken) {
                return;
            }
            //判断用户是否具备当前请求的权限
            for (GrantedAuthority authority : auths) {
                //如果具备权限则结束
                if (configAttribute.getAttribute().equals(authority.getAuthority())) {
                    return;
                }
            }
        }
        throw new AccessDeniedException("权限不足");
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
